﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace UDITest
{
    internal class SerialTool
    {
        List<SerialPort> AllSerial { get; set; } = new List<SerialPort>();

        Action<byte[]> _dataAction;

        private int StringToHex(string str)
        {
            //str = str.Replace("0x", "").Replace("0X", "");
            return Convert.ToInt32(str, 16);
        }

        /// <summary>
        /// 打开设备
        /// </summary>
        /// <param name="vid"></param>
        /// <param name="pid"></param>
        /// <param name="dataAction"></param>
        /// <returns>打开设备数量</returns>
        public int Open(string vid, string pid, Action<byte[]> dataAction)
        {
            var coms = DeviceHelper.GetCOMFromVIDPID(StringToHex(vid), StringToHex(pid));

            foreach (var item in coms)
            {
                Conn(item, dataAction);
            }

            if (AllSerial.Count == 0) throw new Exception("未找到串口设备");

            return AllSerial.Count;
        }


        List<byte> msg = new List<byte>();

        private void Conn(string com, Action<byte[]> dataAction)
        {
            SerialPort serialPort = new SerialPort(com, 115200); // 创建串口实例

            serialPort.Open(); // 打开串口
            _dataAction = dataAction;
            serialPort.DataReceived += SerialPort_DataReceived;
            AllSerial.Add(serialPort);

            Task.Run(() =>
            {
                while (serialPort.IsOpen)
                {
                    if (serialPort.BytesToRead > 0) // 当串口缓冲区中有可读数据时
                    {
                        byte[] buffer = new byte[serialPort.BytesToRead]; // 创建缓冲区
                        serialPort.Read(buffer, 0, buffer.Length); // 读取数据到缓冲区

                        msg.AddRange(buffer);
                        if (msg[msg.Count - 3] == 34 && msg[msg.Count - 2] == 125 && msg[msg.Count - 1] == 93)
                        {
                            dataAction?.Invoke(msg.ToArray());
                            msg.Clear();
                        }
                    }
                }
            });
            
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //var sp = (SerialPort)sender;
            ////_dataAction?.Invoke(Encoding.ASCII.GetBytes(sp.ReadExisting()));

            //int length = sp.BytesToRead;
            //byte[] data = new byte[length];
            //sp.Read(data, 0, length);
            //_dataAction?.Invoke(data);


            //_dataAction?.Invoke(((SerialPort)sender).ReadExisting());
        }

        public void Close()
        {
            foreach (var item in AllSerial)
            {
                try
                {
                    if (item != null)
                    {
                        item.DataReceived -= SerialPort_DataReceived;
                        item.Close();
                        item.Dispose();
                    }
                }
                catch (Exception)
                {

                }
            }
            AllSerial.Clear();
        }
    }
}
